package com.anonymous.community.hotfix;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;

/**
 * 补丁下载器
 * 负责从服务器下载补丁文件并验证
 */
public class PatchDownloader {
    
    private static final String TAG = "PatchDownloader";
    private Context context;
    
    public interface DownloadListener {
        void onStart();
        void onProgress(int progress);
        void onSuccess(String filePath);
        void onError(String error);
    }
    
    public PatchDownloader(Context context) {
        this.context = context.getApplicationContext();
    }
    
    /**
     * 下载补丁文件
     */
    public void downloadPatch(UpdateInfo updateInfo, DownloadListener listener) {
        new DownloadTask(updateInfo, listener).execute();
    }
    
    /**
     * 异步下载任务
     */
    private class DownloadTask extends AsyncTask<Void, Integer, String> {
        
        private UpdateInfo updateInfo;
        private DownloadListener listener;
        private String errorMessage;
        
        public DownloadTask(UpdateInfo updateInfo, DownloadListener listener) {
            this.updateInfo = updateInfo;
            this.listener = listener;
        }
        
        @Override
        protected void onPreExecute() {
            if (listener != null) {
                listener.onStart();
            }
        }
        
        @Override
        protected String doInBackground(Void... voids) {
            try {
                return downloadFile();
            } catch (Exception e) {
                Log.e(TAG, "下载补丁失败", e);
                errorMessage = e.getMessage();
                return null;
            }
        }
        
        @Override
        protected void onProgressUpdate(Integer... values) {
            if (listener != null && values.length > 0) {
                listener.onProgress(values[0]);
            }
        }
        
        @Override
        protected void onPostExecute(String filePath) {
            if (filePath != null) {
                if (listener != null) {
                    listener.onSuccess(filePath);
                }
            } else {
                if (listener != null) {
                    listener.onError(errorMessage != null ? errorMessage : "下载失败");
                }
            }
        }
        
        private String downloadFile() throws Exception {
            URL url = new URL(updateInfo.getDownloadUrl());
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            try {
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(10000);
                connection.setReadTimeout(30000);
                connection.connect();
                
                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    throw new Exception("HTTP错误: " + responseCode);
                }
                
                int fileLength = connection.getContentLength();
                
                // 创建补丁目录
                File patchDir = new File(context.getFilesDir(), HotfixConfig.PATCH_DIR);
                if (!patchDir.exists()) {
                    patchDir.mkdirs();
                }
                
                // 创建补丁文件
                String fileName = "patch_" + updateInfo.getPatchVersion() + ".apk";
                File patchFile = new File(patchDir, fileName);
                
                // 如果文件已存在且MD5匹配，直接返回
                if (patchFile.exists() && verifyMD5(patchFile, updateInfo.getMd5())) {
                    Log.i(TAG, "补丁文件已存在且验证通过: " + patchFile.getAbsolutePath());
                    return patchFile.getAbsolutePath();
                }
                
                // 下载文件
                InputStream input = connection.getInputStream();
                FileOutputStream output = new FileOutputStream(patchFile);
                
                byte[] buffer = new byte[4096];
                long total = 0;
                int count;
                
                while ((count = input.read(buffer)) != -1) {
                    if (isCancelled()) {
                        input.close();
                        output.close();
                        patchFile.delete();
                        return null;
                    }
                    
                    total += count;
                    output.write(buffer, 0, count);
                    
                    // 更新进度
                    if (fileLength > 0) {
                        publishProgress((int) (total * 100 / fileLength));
                    }
                }
                
                output.flush();
                output.close();
                input.close();
                
                // 验证下载的文件
                if (!verifyMD5(patchFile, updateInfo.getMd5())) {
                    patchFile.delete();
                    throw new Exception("文件MD5验证失败");
                }
                
                Log.i(TAG, "补丁下载成功: " + patchFile.getAbsolutePath());
                return patchFile.getAbsolutePath();
                
            } finally {
                connection.disconnect();
            }
        }
    }
    
    /**
     * 验证文件MD5
     */
    private boolean verifyMD5(File file, String expectedMD5) {
        if (expectedMD5 == null || expectedMD5.isEmpty()) {
            Log.w(TAG, "未提供MD5值，跳过验证");
            return true;
        }
        
        try {
            String actualMD5 = calculateMD5(file);
            boolean isValid = expectedMD5.equalsIgnoreCase(actualMD5);
            
            if (isValid) {
                Log.i(TAG, "MD5验证通过: " + actualMD5);
            } else {
                Log.e(TAG, "MD5验证失败 - 期望: " + expectedMD5 + ", 实际: " + actualMD5);
            }
            
            return isValid;
        } catch (Exception e) {
            Log.e(TAG, "MD5验证异常", e);
            return false;
        }
    }
    
    /**
     * 计算文件MD5
     */
    private String calculateMD5(File file) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        InputStream fis = new java.io.FileInputStream(file);
        
        byte[] buffer = new byte[8192];
        int length;
        while ((length = fis.read(buffer)) != -1) {
            md.update(buffer, 0, length);
        }
        fis.close();
        
        byte[] digest = md.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b));
        }
        
        return sb.toString();
    }
    
    /**
     * 清理旧的补丁文件
     */
    public void cleanOldPatches() {
        try {
            File patchDir = new File(context.getFilesDir(), HotfixConfig.PATCH_DIR);
            if (patchDir.exists() && patchDir.isDirectory()) {
                File[] files = patchDir.listFiles();
                if (files != null) {
                    for (File file : files) {
                        if (file.isFile() && file.getName().startsWith("patch_")) {
                            boolean deleted = file.delete();
                            Log.d(TAG, "清理补丁文件: " + file.getName() + " - " + (deleted ? "成功" : "失败"));
                        }
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "清理旧补丁文件失败", e);
        }
    }
}